#pragma once

namespace MySharedPtr {

	template<class T>
	class shared_ptr {

	public:
		shared_ptr(T* ptr)
			:_ptr(ptr),
			_pcount(new int (1))
		{}

		// sp2(sp1)
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr),
			_pcount(sp._pcount)
		{
			(*_pcount)++;
		}

		// sp2 = sp1
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				this->release();

				_ptr = sp._ptr;
				_pcount = sp._pcount;
				(*_pcount) ++;
			}
			return *this;
		}

		void release()
		{
			--(*this->_pcount);

			if (*(this->_pcount) == 0)
			{
				delete _ptr;
				_ptr = nullptr;

				delete _pcount;
				_pcount = nullptr;
			}
		}

		~shared_ptr()
		{
			release();
		}

		int use_count()
		{
			return (*_pcount);
		}

		T& operator*()
		{
			return (*_ptr);
		}

		T* operator->()
		{
			return (_ptr)
		}





	private:	
		T* _ptr;
		int* _pcount;
	};
}